import * as cc from "cc";
import { VMNodeAttr } from "../VMEntity";
import { VMCustomEntity } from "./VMCustomEntity";

declare let CC_EDITOR;
declare let CC_DEV;

export class VMNodeEntity extends VMCustomEntity{
    // @ts-ignore
    observerAttr: VMNodeAttr;
    watchNodes: cc.Node [] = [];
    onBind() {
        if(CC_EDITOR){ return; }
        if(this.observerAttr.controlChildren){
            this.node.on(cc.Node.EventType.CHILD_ADDED,this._onChildrenChanged,this);
            this.node.on(cc.Node.EventType.CHILD_REMOVED,this._onChildrenChanged,this);
            this.node.on(cc.Node.EventType.SIBLING_ORDER_CHANGED,this._onChildrenChanged,this);    
        }
        
    }
    onUnBind() {
        if(CC_EDITOR){ return; }        
        if(this.observerAttr.controlChildren){
            this.node.targetOff(this);
        }
    }
    protected _onChildrenChanged(){
        if(this.observerAttr.controlChildren){
            this.watchNodes.length = 0;
            if(this.node.children.length == 0){
                CC_DEV && console.warn(`VMFactory->VMNodeEntity [${this.node.name}] VMNodeEntity [controlChildren] ,but childrenCount == 0 !!`);                    
            }
            this.watchNodes = this.watchNodes.concat(this.node.children);   
        }
    }
    onValueInit() {
        if(CC_EDITOR){ return; }
        
        if(this.watchNodes.length == 0){
            if(this.observerAttr.controlChildren){
                // if(this.node.children.length == 0){
                //     console.warn(`VMFactory->VMNodeEntity [${this.node.name}] VMNodeEntity [controlChildren] ,but childrenCount == 0 !!`);                    
                // }
                // this.watchNodes = this.watchNodes.concat(this.node.children);  
                this._onChildrenChanged();             
            }else{
                this.watchNodes.push(this.node);
            }
        }
        super.onValueInit();
    }
    onStart() {
        if(CC_EDITOR){ return; }
        
    }
    formatValue(newValue: any,oldValue: any,node: cc.Node,nodeIdx: number,watchPath: string){
        if(this.observerAttr.formator){
         return this.observerAttr.formator.call(this.controllerUserComponent,{
             entity: this,
             newValue,
             oldValue,
             node,
             nodeIdx,
             watchPath
         });
        }
        return newValue;
    }
    
    protected _updateValue(newValue,oldValue,watchPath){
        
        this.watchNodes.forEach((node,index)=>{
            let state = this.formatValue(newValue,oldValue,node,index,watchPath);
            let _property = this._property;

            node[_property] = state;
        })
    }

    get _property(){
        let _observerAttr = this.observerAttr;
        return _observerAttr.property as string;
    }
    onCheckProperty(){        

        return this._property in this.node;
    }
}
